/*
 * Created by SharpDevelop.
 * User: David
 * Date: 2006-11-26
 * Time: 01:39
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;

namespace Labb4.Media.Sfx
{
	/// <summary>
	/// Container class for a Sound object
	/// </summary>
	public class Audio
	{
		#region members
		
		/// <summary>
		/// Reference to the fmod manager
		/// </summary>
		private FMODManager			m_Engine;
		/// <summary>
		/// The sound
		/// </summary>
		private FMOD.Sound			m_Sample;
		/// <summary>
		/// The virtual fmod channel where the sound is played
		/// </summary>
		private FMOD.Channel		m_Output;
		/// <summary>
		/// Determines whether or not this sound is allowed to be played more than once
		/// at the same time. If true, it can be played more than once at the same time,
		/// if false, it can only be played once at a time, and the sound will restart
		/// if it's asked to play while it's allready playing
		/// </summary>
		private bool				m_AllowMultipleInstances;
		
		#endregion
		
		#region constructors
		
		/// <summary>
		/// Constructor, loads the sound found in the given file name
		/// </summary>
		/// <param name="fileName">The name of the file holding the sound to load</param>
		/// <param name="allowMultipleInstances">Set this to false if you want the sound to restart everytime it plays</param>
		public Audio(string fileName, bool allowMultipleInstances)
		{
			m_Engine = FMODManager.Instance;
			m_Sample = m_Engine.GetFMODSound(fileName);
			m_Output = null;
			m_AllowMultipleInstances = allowMultipleInstances;
			
			if(m_Sample != null)
			{
				MediaManager.Instance.AddAudio(fileName, this);
			}
			else
			{
				//TODO report the error of loading file here
				// seems FMOD does this for me in FMODManager.GetFMODSound
			}
		}
		
		//how do I comment destructors?
		//Destructor, calls Release in case that has been forgotten
		~Audio()
		{
			Release();
		}
		
		#endregion
		
		#region methods
		
		/// <summary>
		/// Plays the sound at chosen volume and pan position.
		/// </summary>
		/// <param name="volume">Volume to play at, range 0 - 128</param>
		/// <param name="pan">Pan position to play at, range (-64) - 64</param>
		public void Play(int volume, int pan)
		{
			float v = 1.0f;
			float p = 0.0f;
			
			if((volume > -1) && (volume < 129))
			{
				v = (float)volume / 128.0f;
			}
			
			if((pan > -65) && (pan < 65))
			{
				p = (float)pan / 64.0f;
			}
			
			m_Engine.PlaySample(m_Sample, ref m_Output, !m_AllowMultipleInstances, v, p);
		}
		
		/// <summary>
		/// Releases the memory used by the sound
		/// </summary>
		public void Release()
		{
			FMOD.RESULT result;
			
			if(m_Sample != null)
			{
				result = m_Sample.release();
				m_Engine.ERRCHECK(result);
				m_Sample = null;
			}
		}
		
		#endregion
	}
}
